package com.huawang.mdesign.model.service.controller;

import com.huawang.business.constants.ErrorCode;
import com.huawang.business.constants.ParamErrorConstants;
import com.huawang.business.dto.MergeVariationDTO;
import com.huawang.business.dto.project.ModelDependency;
import com.huawang.business.exception.AbortExecutionException;
import com.huawang.business.service.model.parse.reqif.ReqIfPreviewVo;
import com.huawang.business.vo.CopyResultVo;
import com.huawang.business.vo.ModelResultVo;
import com.huawang.mdesign.model.service.config.WebLogIgnore;
import com.huawang.mdesign.model.service.dto.*;
import com.huawang.mdesign.model.service.vo.*;
import com.huawang.mdesign.model.service.inter.ProjectService;
import com.huawang.util.constants.ExportValueConstants;
import com.huawang.xmlImport.service.CsmParseService;
import com.huawang.xmlImport.service.ExportService;
import com.huawang.xmlImport.vo.ExportXmiDTO;
import com.huawang.xmlImport.vo.Md3DTO;
import com.huawang.xmlImport.vo.ProgressBarVo;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.support.RequestContextUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import java.util.List;

@RestController
@RequestMapping("/project")
@Tag(name = "项目")
@ApiResponses(@ApiResponse(responseCode = "200", description = "接口请求成功"))
@Slf4j
@Validated
public class ProjectController {
    @Autowired
    private ProjectService projectService;

    @Autowired
    @Lazy()
    private CsmParseService csmParseService;

    @Resource
    @Lazy()
    private ExportService exportService;

    @Operation(summary = "项目创建")
    @PostMapping("/create")
    public BaseResponse<ProjectVo> create(@Validated @RequestBody ProjectCreateDTO dto) {
        return BaseResponse.success(projectService.makeVo(projectService.create(dto)));
    }

    @Operation(summary = "模板项目创建")
    @PostMapping("/template/create")
    public BaseResponse<ProjectVo> createTemplate(@Validated @RequestBody ProjectTemplateCreateDto dto) {
        return BaseResponse.success(projectService.makeVo(projectService.createTemplate(dto)));
    }

    @Operation(summary = "项目删除")
    @PostMapping("/delete")
    public BaseResponse<Boolean> delete(@Valid @RequestBody ProjectDeleteDto dto) {
        return BaseResponse.success(projectService.delete(dto.getProjectId(), dto.getSaveWay()));
    }

    @Operation(summary = "从项目文件中打开项目")
    @PostMapping("/openMd3")
    public BaseResponse<ProjectVo> openMd3(@Valid @RequestBody ProjectOpenDTO projectOpenDto) {
        return BaseResponse.success(projectService.makeVo(projectService.openMd3(projectOpenDto)));
    }

    @Operation(summary = "项目转换")
    @PostMapping("/md3Parse")
    public BaseResponse<String> md3Parse(@Valid @RequestBody Md3DTO md3Dto) {
        return BaseResponse.success("");
    }

    @Operation(summary = "csm导入")
    @PostMapping("/csmImport")
    public BaseResponse<String> csmImport(@Valid @RequestBody Md3DTO md3Dto) {
        return BaseResponse.success(csmParseService.csmImport(md3Dto));
    }

    @Operation(summary = "规范性XML导入")
    @PostMapping("/normImport")
    public BaseResponse<String> normImport(@Valid @RequestBody Md3DTO md3Dto) {
        return BaseResponse.success(csmParseService.normImport(md3Dto));
    }

    @Operation(summary = "csm导入进度条")
    @GetMapping("/csmImport/progressBar")
    @WebLogIgnore
    public BaseResponse<ProgressBarVo> progressBar() {
        return BaseResponse.success(csmParseService.progressBar());
    }

    @Operation(summary = "项目下载")
    @GetMapping("/download")
    public BaseResponse<ProjectVo> download(@NotBlank(message = ParamErrorConstants.NO_PROJECT_ID) String projectId,
                                            Boolean isCoWork) {
        return BaseResponse.success(projectService.makeVo(projectService.download(projectId, isCoWork)));
    }

    @Operation(summary = "下载离线项目")
    @GetMapping("/offline/download")
    public BaseResponse<ProjectVo> downloadOffline(@NotBlank(message = ParamErrorConstants.NO_PROJECT_ID) String projectId,
                                                   String newProjectId) {
        return BaseResponse.success(projectService.makeVo(projectService.downloadOffline(projectId, newProjectId)));
    }

    @Operation(summary = "增量版本的，项目下载, 提供协同使用")
    @GetMapping("/download/diff")
    public BaseResponse<ProjectVo> downloadDiff(@NotBlank(message = ParamErrorConstants.NO_PROJECT_ID) String projectId) {
        return BaseResponse.success(projectService.makeVo(projectService.downloadDiff(projectId)));
    }

    @Operation(summary = "项目下载包括profile路径信息")
    @GetMapping("/download/includeProfile")
    public BaseResponse<ProjectIncludeProfileVo> downloadIncludeProfile(@NotBlank(message = ParamErrorConstants.NO_PROJECT_ID) String projectId) {
        return BaseResponse.success(projectService.makeProjectIncludeProfileVo(projectId));
    }

    @Operation(summary = "项目下载，本地项目作为协同项目最新版本")
    @GetMapping("/download/localAsCowork")
    public BaseResponse<ProjectVariationVo> downloadLocalAsCowork(
            @NotBlank(message = ParamErrorConstants.NO_PROJECT_ID) String coworkProjectId,
            @NotBlank(message = ParamErrorConstants.NO_PROJECT_ID) String localProjectId) {
        return BaseResponse.success(projectService.downloadLocalAsCowork(coworkProjectId, localProjectId));
    }

    @Operation(summary = "项目后撤")
    @PostMapping("/undo")
    public BaseResponse<ModelResultVo> undo(@Valid @RequestBody TransactionDTO transactionDto) {
        ModelResultVo resultVo = projectService.undo(transactionDto.getProjectId(), transactionDto.getTransactionId());
        return BaseResponse.success(resultVo);
    }

    @Operation(summary = "项目前进")
    @PostMapping("/redo")
    public BaseResponse<ModelResultVo> redo(@Valid @RequestBody TransactionDTO transactionDto) {
        ModelResultVo resultVo = projectService.redo(transactionDto.getProjectId(), transactionDto.getTransactionId());
        return BaseResponse.success(resultVo);
    }

    @Operation(summary = "包导出校验")
    @PostMapping("/profile/export/check")
    public BaseResponse<List<CheckProfileExportVo>> checkProfileExport(@Valid @RequestBody ProfileExportDTO profileExportDto) {
        return BaseResponse.success(projectService.checkProfileExport(profileExportDto));
    }

    @Operation(summary = "profile导出")
    @PostMapping("/profile/export")
    public BaseResponse<ProjectVo> profileExport(@Valid @RequestBody ProfileExportDTO profileExportDto) {
        return BaseResponse.success(projectService.makeVo(projectService.exportProfile(profileExportDto.getProjectId(),
                profileExportDto.getProfileId(), profileExportDto.getInstanceId(),
                profileExportDto.getDataType(), profileExportDto.getIsPackageExport())));
    }

    @Operation(summary = "模型下发:profile导出")
    @PostMapping("/distribute/profile/export")
    public BaseResponse<DistributeProjectVo> distributeProfileExport(@Valid @RequestBody ProfileExportDTO profileExportDto) {
        return BaseResponse.success(projectService.distributeExportProfile(profileExportDto.getProjectId(),
                profileExportDto.getInstanceId(),
                profileExportDto.getDataType(), profileExportDto.getIsPackageExport()));
    }


    @Operation(summary = "profile导入")
    @PostMapping("/profile/import")
    public BaseResponse<List<ModelDependency>> profileImport(@Valid @RequestBody ProfileImportDTO profileImportDto) {
        return BaseResponse.success(projectService.createDependencyByNewProfile(profileImportDto.getProjectId(),
                profileImportDto.getProfilePath()));
    }

    @Operation(summary = "包导入")
    @PostMapping("/package/import")
    public BaseResponse<CopyResultVo> packageImport(@Valid @RequestBody PackageImportDTO dto) {
        return BaseResponse.success(projectService.importPackage(dto.getProjectId(), dto.getRootId(), dto.getPath()));
    }


    @Operation(summary = "项目列表")
    @GetMapping("/list")
    public BaseResponse<List<String>> list() {
        return BaseResponse.success(projectService.list());
    }

    @Operation(summary = "导入reqif")
    @PostMapping("/reqif/import")
    public BaseResponse<ModelResultVo> importReqif(@Valid @RequestBody final ImportDTO dto) {
        return BaseResponse.success(projectService.importReqIf(dto));
    }

    @Operation(summary = "导入reqif预览")
    @PostMapping("/reqif/preview")
    public BaseResponse<List<ReqIfPreviewVo>> previewReqif(@Valid @RequestBody final ImportReqIfDTO dto) {
        return BaseResponse.success(projectService.previewReqif(dto));
    }

    @Operation(summary = "导入reqifV2")
    @PostMapping("/reqif/importV2")
    public BaseResponse<ModelResultVo> importV2(@Valid @RequestBody final ImportReqIfDTO dto) {
        return BaseResponse.success(projectService.importReqIfV2(dto));
    }

    @Operation(summary = "导入excel")
    @PostMapping("/excel/import")
    public BaseResponse<ModelResultVo> importExcel(@Valid @RequestBody final ImportDTO dto) {
        return BaseResponse.success(projectService.importExcel(dto));
    }

    @Operation(summary = "导出xmi")
    @PostMapping("/exportXmi")
    public BaseResponse<String> exportXmi(@Valid @RequestBody ExportXmiDTO xmiDto) {
        xmiDto.setSource(ExportValueConstants.ARCH);
        projectService.exportXmi(xmiDto);
        return BaseResponse.success("");
    }

    @Operation(summary = "csm导出进度条")
    @GetMapping("/exportXmi/progressBar")
    @WebLogIgnore
    public BaseResponse<ProgressBarVo> exportProgress() {
        return BaseResponse.success(exportService.progressBar());
    }

    @Operation(summary = "导出标准xml文件")
    @PostMapping("/exportStandardXml")
    public BaseResponse<String> exportStandardXml(@Valid @RequestBody ExportXmiDTO xmiDto) {
        projectService.exportStandardXml(xmiDto);
        return BaseResponse.success("");
    }

    @Operation(summary = "下发xmi")
    @PostMapping("/issueXmi")
    public BaseResponse<String> issueXmi(@Valid @RequestBody ExportXmiDTO xmiDto) {
        projectService.issueXmi(xmiDto);
        return BaseResponse.success("");
    }

    @Operation(summary = "项目初始化")
    @PostMapping("/init")
    public BaseResponse<Boolean> init() {
        projectService.init();
        return BaseResponse.success(true);
    }

    @Operation(summary = "项目语言环境修改")
    @GetMapping("/changeLocale")
    @WebLogIgnore
    public BaseResponse<Boolean> changeLocale(HttpServletRequest request, HttpServletResponse response) {
        LocaleResolver resolver = RequestContextUtils.getLocaleResolver(request);
        if (resolver == null) {
            throw AbortExecutionException.build(ErrorCode.SERVICE_ERROR);
        }

        resolver.setLocale(request, response, null);
        return BaseResponse.success(true);
    }

    @Operation(summary = "清除增量数据")
    @PostMapping("/variation/clear")
    public BaseResponse<Boolean> clearVariation(@Valid @RequestBody ModifyProjectDTO modifyProjectDto) {
        projectService.clearVariation(modifyProjectDto.getProjectId());
        return BaseResponse.success(true);
    }

    @Operation(summary = "合并增量数据至当前项目")
    @PostMapping("/mergeVariationToLocal")
    public BaseResponse<ModelResultVo> mergeVariationToLocal(@Valid @RequestBody MergeVariationDTO dto) {
        return BaseResponse.success(projectService.mergeVariationToLocal(dto));
    }

    @Operation(summary = "服务器退回时将增量再合并到内存增量")
    @PostMapping("/combineVariationIntoNowVariationList")
    public BaseResponse<Boolean> combineVariationIntoNowVariationList(@RequestBody MergeVariationDTO mergeVariationDto) {
        projectService.combineVariationIntoNowVariationList(mergeVariationDto);
        return BaseResponse.success(true);
    }

    @Operation(summary = "查询缺失owner的模型")
    @GetMapping("/getOwnerAbsentInstanceIds")
    public BaseResponse<List<String>> getOwnerAbsentInstanceIds(String projectId) {
        return BaseResponse.success(projectService.getOwnerAbsentInstanceIds(projectId));
    }

    @Operation(summary = "模型owner修复")
    @PostMapping("/modelOwnerIdFix")
    public BaseResponse<ModelOwnerFixVo> modelOwnerIdFix(@Valid @RequestBody ModelFixDTO modelFixDto) {
        return BaseResponse.success(projectService.modelOwnerIdFix(modelFixDto));
    }


    @Operation(summary = "判断项目是否有增量")
    @GetMapping("/variation/exist")
    public BaseResponse<Boolean> isExistVariation(@NotBlank(message = ParamErrorConstants.NO_PROJECT_ID) String projectId) {
        return BaseResponse.success(projectService.isExistVariation(projectId));
    }
}
